package xing.service.Interceptor;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import xing.domain.isv.suite.LoginUser;
import xing.domain.page.annotation.Access;
import xing.domain.page.enums.AccessType;
import xing.infrastructure.data.CallResult;
import xing.infrastructure.data.ResultHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/*******************************************************************************************
 * 类描述：  
 *
 * @author: dustin
 * @date： 2017-9-2 17:18
 * @Description: 权限拦截
 * @version 1.0.0
 *
 *
 * Version    Date       ModifiedBy                 Content  
 * -------- ---------    ----------         ------------------------  
 * 1.0.0     2017-9-2    Administrator                            
 *******************************************************************************************
 */
@Component
public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private ResultHolder resultHolder;


    @Value("${web.check-access}")
    private short checkAccess;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //不验证权限
        if(checkAccess==0) return true;

        if(!(handler instanceof HandlerMethod))
            return true;

        // 将handler强转为HandlerMethod, 前面已经证实这个handler就是HandlerMethod
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 从方法处理器中获取出要调用的方法
        Method method = handlerMethod.getMethod();
        // 获取出方法上的Access注解
        Access access = method.getAnnotation(Access.class);
        if (access == null || access.accessType()==AccessType.NONE) {
            // 如果注解为null, 说明不需要拦截, 直接放过
            return true;
        }
        //权限验证
        LoginUser u=LoginUser.getCurrentUser(request);
        logger.info("get current user:{}",u);

        boolean passed=checkRight(response,access,u);
        logger.info("check result:{}",passed);
        return passed;
    }

    private boolean checkRight(HttpServletResponse response,Access access, LoginUser u) throws Exception{
        if(u==null){
            CallResult res= CallResult.error("无操作权限！");
            responseJson(response,JSON.toJSONString(res));
            //resultHolder.setModel(res);
            return false;
        }
        switch (access.accessType()) {
            case LOGIN:
                logger.info("enter login check...");
                return true;//当前用户不为null,说明已经登录
            case ADMIN:
                logger.info("enter admin check...");
                if(!u.getIsSys()){
                    responseJson(response,JSON.toJSONString(CallResult.error("无访问权限！")));
                    return false;
                }
                return true;
        }
        return true;
    }
//    @Override
//    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//
//        CallResult res=resultHolder.getModel();
//        if(res!=null){
//            responseJson(response,JSON.toJSONString(res));
//        }else{
//            super.afterCompletion(request, response, handler, ex);
//        }
//
////        if(resultHolder==null){
////            writeJson(response,"{err}");
////        }else{
////            //String json = JSON.toJSONString(resultHolder.getModel());
////
////        }
//
//        //super.afterCompletion(request, response, handler, ex);
//    }

    private void responseJson(HttpServletResponse response, String json) throws Exception{
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
            //logger.error("response error",e);
            throw e;
        } finally {
            if (writer != null)
                writer.close();
        }
    }

}
